﻿/**
 * Hash.cs - 哈希实现的基类
 * 
 * 作者：Gates_ice
 * 日期：2012年1月18日
 * 说明：
 * 作为哈希实现的基类，提供了算法名称和字节数组转换十六进制字符串的表达方式，实现了IHashable接口。
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace P2PChat.Security.Hasher
{
    /// <summary>
    /// 所有哈希实现的基类，无法创建此类的实体
    /// </summary>
    public abstract class Hash : IHashable
    {
        private readonly string algorithm;
        /// <summary>
        /// 获取该算法的名称
        /// </summary>
        public string Algorithm { get { return algorithm; } }

        /// <summary>
        /// 使用算法名称对类进行初始化
        /// </summary>
        /// <param name="AlgorithmName">哈希算法的名称</param>
        public Hash(string AlgorithmName)
        {
            algorithm = AlgorithmName;
        }

        /// <summary>
        /// 计算字节数组的哈希值，必须在派生类中重写此方法。
        /// </summary>
        /// <param name="data">哈希的数据</param>
        /// <returns>哈希值的字节数组</returns>
        abstract public byte[] ComputeHash(byte[] data);
        /// <summary>
        /// 计算一段数据流的哈希值，必须在派生类中重写此方法。
        /// </summary>
        /// <param name="data">哈希的数据</param>
        /// <returns>哈希值的字节数组</returns>
        abstract public byte[] ComputeHash(System.IO.Stream data);

        /// <summary>
        /// 计算字节数组的哈希值，必须在派生类中重写此方法。
        /// </summary>
        /// <param name="data">哈希的数据</param>
        /// <param name="result">传出哈希值的字符串表达</param>
        /// <returns>哈希值的字节数组</returns>
        abstract public byte[] ComputeHash(byte[] data, out string result);
        /// <summary>
        /// 计算一段数据流的哈希值，必须在派生类中重写此方法。
        /// </summary>
        /// <param name="data">哈希的数据</param>
        /// <param name="result">传出哈希值的字符串表达</param>
        /// <returns>哈希值的字节数组</returns>
        abstract public byte[] ComputeHash(System.IO.Stream data, out string result);

        /// <summary>
        /// 将字节数组转换为16进制表示的字符串
        /// </summary>
        /// <param name="buf">转换的字节数组</param>
        /// <returns>转换的结果</returns>
        protected string ByteArrayToHexString(byte[] buf)
        {
            int iLen = 0;

            // 通过反射获取 MachineKeySection 中的 ByteArrayToHexString 方法，该方法用于将字节数组转换为16进制表示的字符串。
            Type type = typeof(System.Web.Configuration.MachineKeySection);
            System.Reflection.MethodInfo byteArrayToHexString = type.GetMethod("ByteArrayToHexString", BindingFlags.Static | BindingFlags.NonPublic);

            // 字节数组转换为16进制表示的字符串
            return (string)byteArrayToHexString.Invoke(null, new object[] { buf, iLen });
        }
    }
}
